package cn.edu.swu.miniwebsvr.handler;

import cn.edu.swu.miniwebsvr.core.Config;
import cn.edu.swu.miniwebsvr.core.Handler;
import cn.edu.swu.miniwebsvr.core.Parameter;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.charset.StandardCharsets;

public class DefaultHandler implements Handler {

    @Override
    public void handle(Parameter request, OutputStream response) {
        // TODO: [222024321072035/万能]
        // 1. 获取请求路径（可能需要将 / 映射到 index.html）
        // 2. 根据 Config.getWebRoot() 构建完整文件路径

        String requestUrl = request.getUrl();
        String fileName = requestUrl.equals("/") ? "index.html" : requestUrl.substring(1);
        Path filePath = Paths.get(Config.getInstance().getWebRoot(), fileName).normalize();

        // 安全检查：防止路径穿越
        Path webRootPath = Paths.get(Config.getInstance().getWebRoot()).toAbsolutePath().normalize();
        if (!filePath.toAbsolutePath().startsWith(webRootPath)) {
            sendError(response, 403, "Forbidden: Invalid path");
            return;
        }

        try {
            if (Files.exists(filePath) && !Files.isDirectory(filePath)) {
                // 2. 读取文件内容
                byte[] fileBytes = Files.readAllBytes(filePath);

                // 3. 确定Content-Type
                String contentType = Files.probeContentType(filePath);
                if (contentType == null) {
                    contentType = "application/octet-stream";
                }

                // 4. 发送200响应
                String headers = "HTTP/1.1 200 OK\r\n" +
                        "Content-Type: " + contentType + "\r\n" +
                        "Content-Length: " + fileBytes.length + "\r\n" +
                        "Connection: close\r\n" +
                        "\r\n";
                response.write(headers.getBytes(StandardCharsets.UTF_8));
                response.write(fileBytes);
                response.flush();
            } else {
                // 文件不存在
                sendError(response, 404, "Not Found: " + requestUrl);
            }
        } catch (IOException e) {
            // TODO: [222024321072035/万能] 文件读取异常，返回 500 Internal Server Error
            sendError(response, 500, "Internal Server Error");
        }
    }

    // 发送错误响应
    private void sendError(OutputStream response, int statusCode, String message) {
        try {
            String statusText = getStatusText(statusCode);
            String content = String.format("<h1>%d %s</h1><p>%s</p>", statusCode, statusText, message);

            String headers = String.format("HTTP/1.1 %d %s\r\n", statusCode, statusText) +
                    "Content-Type: text/html; charset=UTF-8\r\n" +
                    "Content-Length: " + content.getBytes(StandardCharsets.UTF_8).length + "\r\n" +
                    "Connection: close\r\n" +
                    "\r\n";

            response.write(headers.getBytes(StandardCharsets.UTF_8));
            response.write(content.getBytes(StandardCharsets.UTF_8));
            response.flush();
        } catch (IOException e) {
            // 忽略错误
        }
    }

    // 获取状态码对应的文本描述
    private String getStatusText(int statusCode) {
        switch (statusCode) {
            case 404: return "Not Found";
            case 403: return "Forbidden";
            case 500: return "Internal Server Error";
            default: return "Unknown";
        }
    }
}
